package com.alibaba.cloud.clinic.config.mq;

import com.alibaba.cloud.clinic.constant.ClinicConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMqConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(RabbitMqConfig.class);

    @Autowired
    private ConnectionFactory connectionFactory;

    @Autowired
    private RabbitMqConfirmCallBack confirmCallBack;

    @Autowired
    private RabbitMqReturnsCallBack returnsCallBack;

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setConfirmCallback(confirmCallBack);
        rabbitTemplate.setReturnsCallback(returnsCallBack);
        rabbitTemplate.setMandatory(true);
        confirmCallBack.setRabbitTemplate(rabbitTemplate);
        return rabbitTemplate;
    }

    // Tech

    @Bean(ClinicConstant.TECH_QUEUE)
    public Queue techQueue() {
        return new Queue(ClinicConstant.TECH_QUEUE, true);
    }

    @Bean(ClinicConstant.TECH_EXCHANGE)
    public Exchange techExchange() {

        return ExchangeBuilder.directExchange(ClinicConstant.TECH_EXCHANGE).durable(true).build();
    }

    @Bean
    public Binding techBind(@Qualifier(ClinicConstant.TECH_QUEUE) Queue queue, @Qualifier(ClinicConstant.TECH_EXCHANGE) Exchange exchange) {

        return BindingBuilder.bind(queue).to(exchange).with(ClinicConstant.TECH_ROUTING_KEY).noargs();
    }

    // Transmit

    @Bean(ClinicConstant.TRANS_QUEUE)
    public Queue transQueue() {
        Map<String, Object> map = new HashMap<>();
        map.put("x-dead-letter-exchange", ClinicConstant.DEAD_LETTER_EXCHANGE);
        map.put("x-dead-letter-routing-key", ClinicConstant.DEAD_LETTER_ROUTING_KEY);
        map.put("x-message-ttl", 10000);
        map.put("x-max-length", 1000);
        return new Queue(ClinicConstant.TRANS_QUEUE, true, false, false, map);
    }

    @Bean(ClinicConstant.TRANS_EXCHANGE)
    public Exchange transExchange() {

        return ExchangeBuilder.directExchange(ClinicConstant.TRANS_EXCHANGE).durable(true).build();
    }

    @Bean
    public Binding transBind(@Qualifier(ClinicConstant.TRANS_QUEUE) Queue queue, @Qualifier(ClinicConstant.TRANS_EXCHANGE) Exchange exchange) {

        return BindingBuilder.bind(queue).to(exchange).with(ClinicConstant.TRANS_ROUTING_KEY).noargs();
    }
}
